#pragma once
#include "tokens.h"
#include <string>
#include <map>
#include <vector>

namespace krryn{
namespace parsers{
	class parser_list{
	public:
		void parse(std::istream &a_Input);
		virtual void handle_token(tokens_list a_Token, std::string a_Text) = 0;
	};

	struct parser_list_node{
	public:
		std::string m_Name;
		std::map<std::string, std::vector<std::string>* > m_Properties;
		std::vector<parser_list_node*> m_Children;
		parser_list_node *m_Parent;

		parser_list_node() : m_Parent(0) {}
		parser_list_node(const std::string &a_Name) : m_Name(a_Name), m_Parent(0) {}

		parser_list_node* add_child(parser_list_node *a_Node){
			m_Children.push_back(a_Node);
			a_Node->m_Parent = this;
			return a_Node;
		}
	};

	class parser_list_action{
	public:
		virtual void accept(parser_list_node *a_Node) = 0;
	};

	class parser_parse_list : public parser_list{
	public:
		parser_parse_list();

		// \note this function relies on being called one time to many
		// the last time should be called with tok_list_end
		virtual void handle_token(tokens_list a_Token, std::string a_Text);

		//! Has one token to look ahead
		void delayed_token(tokens_list a_CurrentToken, tokens_list a_NextToken, 
			std::string a_CurrentText,  std::string a_NextText);

		parser_list_node *get_root() { return m_Root; }

		//! DEPRECATED!!! (Should be removed in the near future)
		void walk(parser_list_action *a_List);
	private:
		void walk_recursive(parser_list_action *a_List, parser_list_node *a_Node);

		tokens_list m_PreviousToken;
		std::string m_PreviousText;
		bool m_IsFirstToken;
		size_t m_ExpectedIndent, m_ActualIndent;

		bool m_IsRootProperty;
		bool m_PropertyList;
		std::string m_CurrentProperty;

		parser_list_node *m_Root;
		parser_list_node *m_Current;
	};

	// prints a brief overview of the contents of the file
	class pretty_print_list{
	public:
		void print(krryn::parsers::parser_list_node &a_Node, int indent = 0);
	};
}
}
